package com.zofer.study.thread.blockqueue;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description 手写一个阻塞队列
 * @date: 2020/10/20 11:19
 */
public class HandWriteQueue {
    private List<String> list = new ArrayList<>();
    private int count;
    private Lock lock = new ReentrantLock();
    private final Condition nullCondition = lock.newCondition();
    private final Condition fullCondition = lock.newCondition();

    /**
     * 添加
     */
    public void push(String item){
        if (item == null || "".equals(item)){
            throw new NullPointerException();
        }
        try {
            lock.lock();
            ++count;
            System.out.println(">>>ready push:"+item);
            list.add(item);
            nullCondition.signal();
            System.out.println(">>>pushed:"+item);
        } catch (Exception e) {
            e.printStackTrace();
            nullCondition.signal();
        } finally {
            lock.unlock();
        }
    }


    /**
     * 获取
     */
    public String poll(){
        String item = null;
        try {
            lock.lock();
            if (list == null || list.size() == 0){
                System.out.println(">>>poll list is null");
                nullCondition.await();
            }
            --count;
            System.out.println(">>>ready poll");
            item = list.get(0);
            list.remove(0);
            System.out.println(">>>poll:"+item);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return item;
    }


    public static void main(String[] args) {
        final HandWriteQueue handWriteQueue = new HandWriteQueue();
        Thread threadPush = new Thread(){
            @Override
            public void run() {
                handWriteQueue.push("1");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handWriteQueue.push("2");
            }
        };

        Thread threadPoll = new Thread(){
            @Override
            public void run() {
                while (true){
                    handWriteQueue.poll();
                }
            }
        };

        threadPush.start();
        threadPoll.start();

    }

}
